package unei.net.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 * Created by sunlei on 2015/8/31.
 */
public class NioServer implements Runnable{
    private ServerSocket serverSocket;
    private SelectorSelection selectorSelection;

    public NioServer(String uri,int port) throws IOException {
        ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();

        serverSocketChannel.bind(new InetSocketAddress(uri,port));
        this.serverSocket=serverSocketChannel.socket();
    }

    public void run() {
        final ServerSocketChannel channel=serverSocket.getChannel();

        try {
            channel.configureBlocking(false);

            selectorSelection=SelectorManager.getInstance().register(channel,new SelectorManager.Listener(){

                public void onSelect(SelectorSelection selectorSelection) {
                    try {
                        SocketChannel ch=channel.accept();
                        if(ch!=null){
                            handleSocket(ch.socket());
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                public void onError(SelectorSelection selectorSelection, Throwable throwable) {

                }
            });

            selectorSelection.setInterestOps(SelectionKey.OP_ACCEPT);
            selectorSelection.enable();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void handleSocket(Socket socket) throws IOException{
        SocketChannel socketChannel=socket.getChannel();
        socketChannel.configureBlocking(false);
        SelectorSelection ss=SelectorManager.getInstance().register(socketChannel, new SelectorManager.Listener() {
            @Override
            public void onSelect(SelectorSelection selectorSelection) {
                serviceRead(selectorSelection, socket);
            }

            @Override
            public void onError(SelectorSelection selectorSelection, Throwable throwable) {

            }
        });
        ss.setInterestOps(SelectionKey.OP_READ);
        ss.enable();
    }

    public void serviceRead(SelectorSelection selectorSelection, Socket socket){
        final NioTransport transport=new NioTransport(selectorSelection,socket);
        transport.setNioServer(this);
        NioConnector.getExecutor().execute(new Runnable(){
            @Override
            public void run() {
                transport.receive();
            }
        });
    }

    public void serviceWrite(){

    }

    public void doReceive(NioTransport transport,String cmd) throws IOException {
        System.out.println("receive:"+cmd);
//        if(cmd.equals("haha")){
            send(transport.getSocket(),"heihei");
//        }
    }

    public void send(Socket socket,String cmd) throws IOException {
//        SocketChannel socketChannel=socket.getChannel();
//        socketChannel.configureBlocking(false);
//        SelectorSelection ss=SelectorManager.getInstance().register(socketChannel, new SelectorManager.Listener() {
//            @Override
//            public void onSelect(SelectorSelection selectorSelection) {
                NioTransport transport=new NioTransport(null,socket);
                transport.send(cmd);
//            }
//
//            @Override
//            public void onError(SelectorSelection selectorSelection, Throwable throwable) {
//
//            }
//        });
//
//        ss.setInterestOps(SelectionKey.OP_WRITE);
//        ss.enable();
    }
}
